#include <bits/stdc++.h>

#define endl "\n"
#define int long long

using namespace std;

const long double eps = 1e-8;

struct node
{
    int l, r;
} t[1000010];

bool cmp(node a, node b)
{
    return a.r < b.r;
}

int a[1000010];
int b[1000010];
int tr[1000010];
int d1[1000010];
int v1[1000010];
int a1[1000010];

int lowbit(int x)
{
    return x & -x;
}

void update(int x, int c)
{
    if (x < 0) return ;
    for (int i = x; i <= 1000000; i += lowbit(i)) tr[i] += c;
}

int query(int x)
{
    if (x < 0) return 0;
    int res = 0;
    for (int i = x; i; i -= lowbit(i))
        res += tr[i];
    return res;
}

signed main()
{
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int T; cin >> T;
    while (T -- )
    {
        int n, m, L, V, tot = 0;
        cin >> n >> m >> L >> V;
        for (int i = 1; i <= n; i ++ )
            cin >> d1[i] >> v1[i] >> a1[i];
        for (int i = 0; i <= 1000000; i ++ ) tr[i] = 0;
        for (int i = 1; i <= m; i ++ )
        {
            cin >> b[i];
            update(b[i], 1);
        }
        for (int i = 1; i <= n; i ++ )
        {
            int d = d1[i], v = v1[i], a = a1[i];
            if (a == 0)
            {
                if (v > V)
                {
                    if (query(L) - query(d - 1) >= 1)
                        t[ ++ tot] = (node){d, L};
                    //cout << i << " " << d << " " << L << endl;
                }
                continue;
            }
            long double t1 = (V * V * 1.0 - v * v * 1.0) / (2.0 * a);
            if (fabs(t1 - ((int)t1 * 1.0)) < eps)
            {
                int t2 = floor(t1);
                if (a < 0)
                {
                    if (t2 < 0) t2 = 0;
                    int l = d, r = d + t2 - 1;
                    r = min(r, L), l = max(l, 1ll);
                    r = min(r, d + (int)ceil(v * v * 1.0 / (-2.0 * a) - 1));
                    if (query(r) - query(l - 1) >= 1)
                        t[ ++ tot] = (node){l, r};
                    //cout << i << " " << l << " " << r << endl;
                }
                else
                {
                    if (t2 < 0) t2 = 0;
                    int l = d + t2 + 1, r = L;
                    r = min(r, L), l = max(l, 1ll);
                    if (query(r) - query(l - 1) >= 1)
                        t[ ++ tot] = (node){l, r};
                    //cout << i << " " << l << " " << r << endl;
                }
            }
            else
            {
                if (a < 0)
                {
                    if (t1 < 0) t1 = 0;
                    int l = d, r = floor(t1) + d;
                    r = min(r, L), l = max(l, 1ll);
                    r = min(r, d + (int)ceil(v * v * 1.0 / (-2.0 * a) - 1));
                    if (query(r) - query(l - 1) >= 1)
                        t[ ++ tot] = (node){l, r};
                    //cout << i << " " << l << " " << r << endl;
                }
                else
                {
                    if (t1 < 0) t1 = 0;
                    int l = d + ceil(t1), r = L;
                    r = min(r, L), l = max(l, 1ll);
                    if (query(r) - query(l - 1) >= 1)
                        t[ ++ tot] = (node){l, r};
                    //cout << i << " " << l << " " << r << endl;
                }
            }
        }
        sort(t + 1, t + tot + 1, cmp);
        int res = 0, mx = 0;
        int mn = 0x3f3f3f3f3f3f3f3f;
        for (int i = 1; i <= tot; i ++ )
        {
            mx = max(mx, t[i].l);
            mn = min(mn, t[i].r);
            int l = 1, r = m;
            while (l < r)
            {
                int mid = (l + r) / 2;
                if (mx <= b[mid]) r = mid;
                else l = mid + 1;
            }
            if (b[l] > mn)
            {
                mx = t[i].l;
                mn = t[i].r;
                res ++ ;
            }
        }
        if (tot >= 1) res ++ ;
        cout << tot << " " << m - res << endl;
    }

    return 0;
}
